package org.example.lethear.repository;

import org.example.lethear.entity.File;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 文件数据访问接口
 */
@Repository
public interface FileRepository extends JpaRepository<File, Long> {
    
    /**
     * 根据用户ID查找文件
     */
    List<File> findByUserId(Long userId);
    
    /**
     * 根据用户ID分页查找文件
     */
    Page<File> findByUserId(Long userId, Pageable pageable);
    
    /**
     * 根据文件名查找文件
     */
    Optional<File> findByFilename(String filename);
    
    /**
     * 根据文件路径查找文件
     */
    Optional<File> findByFilePath(String filePath);
    
    /**
     * 根据文件类型查找文件
     */
    List<File> findByFileType(String fileType);
    
    /**
     * 根据文件类型分页查找文件
     */
    Page<File> findByFileType(String fileType, Pageable pageable);
    
    /**
     * 根据原始文件名模糊搜索
     */
    @Query("SELECT f FROM File f WHERE f.originalName LIKE %:keyword%")
    Page<File> searchByOriginalName(@Param("keyword") String keyword, Pageable pageable);
    
    /**
     * 根据文件大小范围查找文件
     */
    @Query("SELECT f FROM File f WHERE f.fileSize BETWEEN :minSize AND :maxSize")
    Page<File> findByFileSizeBetween(@Param("minSize") Long minSize, 
                                    @Param("maxSize") Long maxSize, 
                                    Pageable pageable);
    
    /**
     * 查找指定时间段内上传的文件
     */
    @Query("SELECT f FROM File f WHERE f.createTime BETWEEN :startTime AND :endTime")
    Page<File> findFilesByCreateTimeBetween(@Param("startTime") LocalDateTime startTime, 
                                           @Param("endTime") LocalDateTime endTime, 
                                           Pageable pageable);
    
    /**
     * 查找最新上传的文件
     */
    @Query("SELECT f FROM File f ORDER BY f.createTime DESC")
    Page<File> findRecentFiles(Pageable pageable);
    
    /**
     * 查找图片文件
     */
    @Query("SELECT f FROM File f WHERE f.fileType IN ('jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp')")
    Page<File> findImageFiles(Pageable pageable);
    
    /**
     * 查找文档文件
     */
    @Query("SELECT f FROM File f WHERE f.fileType IN ('pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt')")
    Page<File> findDocumentFiles(Pageable pageable);
    
    /**
     * 查找视频文件
     */
    @Query("SELECT f FROM File f WHERE f.fileType IN ('mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv')")
    Page<File> findVideoFiles(Pageable pageable);
    
    /**
     * 查找音频文件
     */
    @Query("SELECT f FROM File f WHERE f.fileType IN ('mp3', 'wav', 'flac', 'aac', 'ogg')")
    Page<File> findAudioFiles(Pageable pageable);
    
    /**
     * 统计用户上传的文件数量
     */
    @Query("SELECT COUNT(f) FROM File f WHERE f.userId = :userId")
    long countByUserId(@Param("userId") Long userId);
    
    /**
     * 统计某种类型的文件数量
     */
    @Query("SELECT COUNT(f) FROM File f WHERE f.fileType = :fileType")
    long countByFileType(@Param("fileType") String fileType);
    
    /**
     * 统计用户上传文件的总大小
     */
    @Query("SELECT SUM(f.fileSize) FROM File f WHERE f.userId = :userId")
    Long sumFileSizeByUserId(@Param("userId") Long userId);
    
    /**
     * 统计今日上传的文件数量
     */
    @Query("SELECT COUNT(f) FROM File f WHERE f.createTime >= :startOfDay")
    long countTodayFiles(@Param("startOfDay") LocalDateTime startOfDay);
    
    /**
     * 查找大文件（超过指定大小）
     */
    @Query("SELECT f FROM File f WHERE f.fileSize > :minSize ORDER BY f.fileSize DESC")
    Page<File> findLargeFiles(@Param("minSize") Long minSize, Pageable pageable);
    
    /**
     * 按文件类型统计数量
     */
    @Query("SELECT f.fileType, COUNT(f) FROM File f GROUP BY f.fileType ORDER BY COUNT(f) DESC")
    List<Object[]> countByFileTypeGrouped();
    
    /**
     * 查找用户的头像文件（根据文件路径pattern）
     */
    @Query("SELECT f FROM File f WHERE f.userId = :userId AND f.filePath LIKE '%avatar%'")
    List<File> findUserAvatars(@Param("userId") Long userId);
    
    /**
     * 删除用户的所有文件记录（用户注销时）
     */
    void deleteByUserId(Long userId);
    
    /**
     * 检查文件名是否已存在
     */
    boolean existsByFilename(String filename);
    
    /**
     * 检查文件路径是否已存在
     */
    boolean existsByFilePath(String filePath);
} 